package com.herr.springboot.self.xxx.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.herr.springboot.self.xxx.common.constant.APIConstant;
import com.herr.springboot.self.xxx.common.entity.ApiRequestLog;
import com.herr.springboot.self.xxx.common.entity.ApiResponseLog;
import com.herr.springboot.self.xxx.common.entity.ApiResult;
import lombok.extern.slf4j.Slf4j;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 日志工具类
 *
 * @author herr05
 */
@Slf4j
public class LogUtils {

    public static void doAfterReturning(Object ret) {
        HttpServletRequest request=ApplicationUtils.getRequest();
        Object beginTime=request.getAttribute(APIConstant.API_BEGIN_TIME);
        ApiResponseLog apiResponseLog = ApiResponseLog.builder()
                .requestId((String)request.getAttribute(APIConstant.API_GUID))
                .requestUri(request.getRequestURI())
                .requestMethod(request.getMethod())
                .result(ret)
                .runTime((beginTime != null ? System.currentTimeMillis() - (long)beginTime : 0) + "ms")
                .build();

        log.info("response: " + JSON.toJSONString(apiResponseLog));
    }

//    public static void doAfterException(Exception ex) {
//        HttpServletRequest request=ApplicationUtils.getRequest();
//        Object beginTime=request.getAttribute(APIConstant.API_BEGIN_TIME);
//        ApiResponseLog apiResponseLog = ApiResponseLog.builder()
//                .requestId((String)request.getAttribute(APIConstant.API_GUID))
//                .requestUri(request.getRequestURI())
//                .requestMethod(request.getMethod())
//                .result(ex.getMessage())
//                .runTime((beginTime != null ? System.currentTimeMillis() - (long)beginTime : 0) + "ms")
//                .build();
//
//        log.info("exception response: " + JSON.toJSONString(apiResponseLog));
//    }

    public static void doAfterException(ApiResult apiResult) {
        HttpServletRequest request=ApplicationUtils.getRequest();
        Object beginTime=request.getAttribute(APIConstant.API_BEGIN_TIME);
        ApiResponseLog apiResponseLog = ApiResponseLog.builder()
                .requestId((String)request.getAttribute(APIConstant.API_GUID))
                .requestUri(request.getRequestURI())
                .requestMethod(request.getMethod())
                .result(apiResult)
                .runTime((beginTime != null ? System.currentTimeMillis() - (long)beginTime : 0) + "ms")
                .build();

        log.info("exception response: " + JSON.toJSONString(apiResponseLog));
    }

    /**
     * 请求参数日志
     * @param request
     */
    public static void logRequestParams(HttpServletRequest request,CustomCachingRequestWrapper wrapperRequest) {
        if (log.isInfoEnabled()) {
            String requestBody = new String(wrapperRequest.getBody());
            Enumeration<String> headerNames = request.getHeaderNames();
            Map<String, String> requestHeaderMap= new HashMap<>();
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                if (name != null) {
                    String value = request.getHeader(name);
                    requestHeaderMap.put(name,value);
                }
            }
            //可能是文件等流无法解析成json，则忽略
            if (!CommonUtils.isJsonObject(requestBody)){
                requestBody="";
            }
            ApiRequestLog apiRequestLog = ApiRequestLog.builder()
                    .requestId((String) request.getAttribute(APIConstant.API_GUID))
                    .requestMethod(request.getMethod())
                    .requestUri(request.getRequestURI())
                    .requestHeaders(requestHeaderMap)
                    .requestParams(request.getParameterMap())
                    .requestBody(Optional.ofNullable(JSONObject.parseObject(requestBody, Object.class)).orElse(requestBody))
                    .requestIp(CommonUtils.getIpAddr(request))
                    .build();
            log.info("request: " + JSON.toJSONString(apiRequestLog));
        }
    }



}
